package com.bonc.apim.controller;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bonc.apim.constant.BaseConstant;
import com.bonc.apim.dao.ApplicationApproveDao;
import com.bonc.apim.dao.RecordDao;
import com.bonc.apim.dao.SubscribeDao;
import com.bonc.apim.entity.ApplicationApprove;
import com.bonc.apim.entity.JsonResult;
import com.bonc.apim.entity.Record;
import com.bonc.apim.entity.Subscribe;
import com.bonc.apim.utils.WebClientUtil;

/**
 * 
 * 应用创建删除审核功能
 *
 * @author wjx
 * @version 2017年10月4日
 * @see ApplicationApproveController
 * @since
 */
@Controller
public class ApplicationApproveController {
    
    private static final Log log = LogFactory.getLog(ApplicationApproveController.class);


    @Value("${processDefinitionId}")
    private String processDefinitionId;
    
    @Value("${appModelKey}")
    private String appModelKey;
    
    @Value("${tenantId}")
    private String tenantId;
    
    @Value("${bpmStartProcessURL}")
    private String bpmStartProcessURL;
    
    @Value("${bpmCompleteTaskURL}")
    private String bpmCompleteTaskURL;
    
    @Value("${bpmIframeNameUrl}")
    private String bpmIframeNameUrl;
    
    @Value("${bpmTrackURL}")
    private String bpmTrackURL;
    
    @Value("${apimAppURL}")
    private String apimAppURL;

    @Autowired
    private ApplicationApproveDao appDao;
    
    @Autowired
    private RecordDao recordDao;

     /**
     * 启动应用流程
     */
    @RequestMapping("/startAppProcess")
    @ResponseBody
    public Object startAppProcess(String applicationCreator, String approveCreator, String applicationName,String description, 
                                  String tenant_id, Integer approveType,String targat_tenantId, String callback, String tier, String callbackUrl) {
        /* 如果API状态不是审核中，则重新启动订阅流程 */
        List<ApplicationApprove> appInfoList = appDao.findByApplicationNameAndApplicationCreatorAndApproveCreatorAndApproveTypeAndApiApproveStatus(
            applicationName, applicationCreator, approveCreator, approveType, BaseConstant.API_APPROVING);
        if (!CollectionUtils.isEmpty(appInfoList)) {
            return buildReturn(callback, new JsonResult("流程正在审核中", BaseConstant.RETURN_CODE_ERROR));
        }
        //System.out.println(targat_tenantId);
        ApplicationApprove application = new ApplicationApprove();
        application.setTenantId(tenant_id);
        application.setApplicationName(applicationName);
        application.setApproveCreator(approveCreator);
        application.setApplicationCreator(applicationCreator);
        application.setTier(tier);
        application.setDescription(description);
        application.setCallbackUrl(callbackUrl);
        application.setApproveType(approveType);//0:创建   1:删除
        application.setApproveStartTime(new Date());
        application.setApiApproveStatus(BaseConstant.API_APPROVING);// 状态
        appDao.save(application);
        //System.out.println(application.toString());
        /** 获取bpm流程启动返回流程实例id */
        String jsonData = null;
        try {
            jsonData = WebClientUtil.doGet(bpmStartProcessURL + "?modelKey=" + appModelKey + "&approveCreator="
                + approveCreator + "&applicationCreator=" + applicationCreator + "&appInfoId=" + application.getId() 
                + "&applicationName="+applicationName + "&tier="+tier + "&approveType="+approveType +"&tenant_id=" + tenantId + 
                "&targat_tenantId="+targat_tenantId + "&loginId=" + approveCreator, null);
//          TODO    下次修改时在启动流程时添加脚本调用url地址方便修改
            JSONObject jsonObject = JSON.parseObject(jsonData);
            application.setProInsId( (String) jsonObject.get("processInstanceId"));
            appDao.save(application);
            log.info("tenant_id=" + tenantId);
            
            //如果流程启动失败，删除不完整的数据
//          if (StringUtils.isEmpty((String)jsonObject.get("processInstanceId")) ) {
//              subDao.delete(subscribe.getId());
//              return buildReturn(callback, new JsonResult("审核流程启动失败，请联系管理员", BaseConstant.RETURN_CODE_ERROR));
//          }else {
//              subscribe.setProInsId( (String) jsonObject.get("processInstanceId"));
//              subDao.save(subscribe);
//              System.out.println("tenant_id=" + tenant_id);
//          }
        } catch (Exception e) {
            // 流程启动失败后，删除添加的数据
            appDao.delete(application.getId());
            log.error("the process start is fail,response:"+jsonData , e);
            return buildReturn(callback, new JsonResult("审核流程启动失败，请联系管理员", BaseConstant.RETURN_CODE_ERROR));
        }
        return buildReturn(callback, new JsonResult("新的流程启动成功", BaseConstant.RETURN_CODE_OK));
    }
    
    /**
     * 办理审核流程
     * @param flowInstId 流程实例id
     * @param taskId 当前流程任务id
     * @param approvalOrlookFlag 办理或办理成功后查看 标志
     * @return
     */
    @RequestMapping("/approveApplication")
    public ModelAndView approveApplication(String flowInstId, String taskId, String approvalOrlookFlag, String user) {

        ApplicationApprove application = appDao.findByProInsId(flowInstId);
        List<Record> recordList = recordDao.findByProInsId(flowInstId);
        ModelAndView model = new ModelAndView();
        model.addObject("proInsId", flowInstId);
        model.addObject("taskId", taskId);
        model.addObject("application", application);
        model.addObject("recordList", recordList);
        model.addObject("loginUser", user);

        /** 判断bpm工单是跳往办理页面或者查看页面 */
        if ("approval".equals(approvalOrlookFlag)) {
            model.setViewName("applicationApproval.jsp");
        } else if ("look".equals(approvalOrlookFlag)) {
            model.setViewName("applicationApprovalScan.jsp");
        }
        return model;
    }

    /**
     * 完成任务节点
     * @param proInsId 流程id
     * @param taskId 任务id
     * @param approvalSumup 提交同意(1 pass)，不同意(0 nopass)
     * @param remark 审批意见
     * @return
     */
    @RequestMapping("/completeAppTask")
    public String completeTask(String proInsId, String taskId, String approvalSumup, String remark, String user) {
            
        ApplicationApprove application = appDao.findByProInsId(proInsId);
        if (BaseConstant.APPROVAL_PASS == Integer.valueOf(approvalSumup)) {
            WebClientUtil.doGet(
                    bpmCompleteTaskURL + "?taskId=" + taskId + "&action=pass" + "&loginId=" + application.getApproveCreator() 
                    + "&tenant_id=" + tenantId , null);
            application.setApiApproveStatus(BaseConstant.API_APPROVED_PASS);// 更新API审核状态:完成
            appDao.save(application);
            addRecord(application, taskId, remark, BaseConstant.APPROVAL_PASS, user);
        } else if (BaseConstant.APPROVAL_NOPASS == Integer.valueOf(approvalSumup)) {
            WebClientUtil.doGet(
                    bpmCompleteTaskURL + "?taskId=" + taskId + "&action=nopass" + "&loginId=" + application.getApproveCreator() 
                    + "&tenant_id=" + tenantId, null);
            application.setApiApproveStatus(BaseConstant.API_APPROVED_NOPASS);// 更新API审核状态:完成
            appDao.save(application);
            addRecord(application, taskId, remark, BaseConstant.APPROVAL_NOPASS, user);
        }
        return "redirect:"+bpmIframeNameUrl;
    }

    /**
     * 通过调用脚本
     * 
     * @param subInfoId 主键
     * @return
     * @throws IOException
     */
    @RequestMapping("/apimAppInvokePass")
    public String apimInvokePass(long appInfoId) {

        log.info("bpm js process  invoke: pass" + appInfoId);
        ApplicationApprove application = appDao.findById(appInfoId);
        String url = apimAppURL + "?approveCreator=" + application.getApproveCreator() + 
                "&applicationCreator=" + application.getApplicationCreator() + "&description="+application.getDescription() + 
                "&appInfoId=" + application.getId() + "&applicationName="+application.getApplicationName() + 
                "&approveType=" + application.getApproveType() +"&tenant_id=" + application.getTenantId() + 
                "&tier=" + application.getTier() + "&callbackUrl=" + application.getCallbackUrl() + "&status=pass";

        String jsonData = WebClientUtil.doGet(url, null);
        log.debug("apim invoke request---------------------" + url);
        log.debug("apim invoke response---------------------" + jsonData);

        return "redirect:"+bpmIframeNameUrl;
    }

    /**
     * 不通过脚本调用
     * @return
     */
    @RequestMapping("/apimAppInvokeNoPass")
    public String apimInvokeNoPass(long appInfoId) {

        log.info("bpm js process  invoke: nopass" + appInfoId);
        ApplicationApprove application = appDao.findById(appInfoId);
        String url = apimAppURL + "?approveCreator=" + application.getApproveCreator() + 
            "&applicationCreator=" + application.getApplicationCreator() + "&description="+application.getDescription() + 
            "&appInfoId=" + application.getId() + "&applicationName="+application.getApplicationName() + 
            "&approveType=" + application.getApproveType() +"&tenant_id=" + application.getTenantId() + 
            "&tier=" + application.getTier() + "&callbackUrl=" + application.getCallbackUrl() + "&status=nopass";

        String jsonData = WebClientUtil.doGet(url, null);
        log.debug("apim invoke request---------------------" + url);
        log.debug("apim invoke response---------------------" + jsonData);

        return "redirect:"+bpmIframeNameUrl;
    }
    
    /**
     * 进入查看页面
     * @return
     */
    @RequestMapping("/lookAproApp")
    public ModelAndView lookAproApi(String flowInstId) {

        ApplicationApprove application = appDao.findByProInsId(flowInstId);
        List<Record> recordList = recordDao.findByProInsId(flowInstId);
        ModelAndView model = new ModelAndView();
        model.addObject("proInsId", flowInstId);
        model.addObject("application", application);
        model.addObject("recordList", recordList);

        model.setViewName("applicationApprovalScan.jsp");
        return model;
    }
    
    /**
     * 进入流程跟踪页面
     * @return
     */
    @RequestMapping("/trackAppProccess")
    public String trackProccess(String flowInstId) {

        return "redirect:"+bpmTrackURL+"?params.pId="+flowInstId;
    }
    
    /**
     * 添加流程记录
     * @param subscribe
     * @param taskId
     * @param remark
     * @return
     */
    private void addRecord(ApplicationApprove application, String taskId, String remark, int status, String loginUser) {
        Record record = new Record();
        record.setProInsId(application.getProInsId());
        record.setApprover(loginUser);
        record.setTaskId(taskId);
        record.setView(remark);
        record.setCreateDate(new Date());
        record.setRecordApproveStatus(status);
        recordDao.save(record);
    }

    /**
     * 判断返回json对象，jsop
     * @param callback
     * @param jsonResult
     * @return
     */
    private Object buildReturn(String callback, JsonResult jsonResult) {
        if (!StringUtils.isEmpty(callback)) {
            return callback + "(" + JSON.toJSONString(jsonResult) + ")";
        }
        return jsonResult;
    }
}
